home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / Snippets / Sound / Double Buffer / DoubleBuffer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-11  |  3.0 KB  |  126 lines  |  [TEXT/MPS ]

  1. #include    <Resources.h>
  2. #include    <Sound.h>
  3. #include    <Memory.h>
  4.  
  5. #define    TRUE            0xFF
  6. #define    FALSE            0
  7. #define kDoubleBufferSize    0x1000
  8.  
  9. struct LocalVars {
  10.     long    bytesTotal;
  11.     long    bytesCopied;
  12.     Ptr        dataPtr;
  13. };
  14.  
  15. typedef struct LocalVars LocalVars;
  16. typedef LocalVars *LocalVarsPtr;
  17.  
  18. pascal void MyDoubleBackProc (SndChannelPtr channel,
  19.                                             SndDoubleBufferPtr doubleBufferPtr);
  20.  
  21. main()
  22. {
  23. SndDoubleBufferHeader    doubleHeader;
  24. SndDoubleBufferPtr        doubleBuffer;
  25. int                        i;
  26. OSErr                    err;
  27. SCStatus                Stats;
  28. SndChannelPtr            chan;
  29. SoundHeaderPtr            Head;
  30. Handle                    SoundData;
  31. LocalVars                myVars;
  32.  
  33. SoundData = GetResource ('snd ', 100);
  34. if (ResError() != noErr || SoundData == nil)
  35.     Debugger();
  36. HLock (SoundData);
  37.  
  38. chan = nil;
  39. err = SndNewChannel (&chan, sampledSynth, 0, nil);
  40. if (err != noErr)
  41.     Debugger();
  42.     
  43. Head = (SoundHeaderPtr) NewPtrClear (sizeof(SoundHeader));
  44. Head->samplePtr = *SoundData;
  45. Head->length = 45838;
  46. Head->sampleRate = 0x56EE8BA3;        //recorded at 22KHz
  47. Head->loopStart = 0;
  48. Head->loopEnd = 0;
  49. Head->encode = 0;
  50. Head->baseFrequency = 60;
  51. Head->sampleArea[0] = 0;
  52.  
  53. myVars.bytesTotal = Head->length;
  54. myVars.bytesCopied = 0;
  55. myVars.dataPtr = Head->samplePtr;
  56.  
  57. doubleHeader.dbhNumChannels = 1;
  58. doubleHeader.dbhSampleSize = 8;
  59. doubleHeader.dbhCompressionID = 0;
  60. doubleHeader.dbhPacketSize = 0;
  61. doubleHeader.dbhSampleRate = Head->sampleRate;
  62.  
  63. /* create a UPP for the SndDoubleBackProc */
  64. doubleHeader.dbhDoubleBack = NewSndDoubleBackProc (MyDoubleBackProc);
  65.  
  66. for (i = 0; i <= 1; ++i) {
  67.     doubleBuffer = (SndDoubleBufferPtr) NewPtrClear (sizeof(SndDoubleBuffer) + kDoubleBufferSize);
  68.     
  69.     if (doubleBuffer == nil || MemError() != 0)
  70.         Debugger();
  71.         
  72.     doubleBuffer->dbNumFrames = 0;
  73.     doubleBuffer->dbFlags = 0;
  74.     doubleBuffer->dbUserInfo [0] = (long) &myVars;
  75.     
  76.     MyDoubleBackProc (chan, doubleBuffer);            // initialize the buffers
  77.     
  78.     doubleHeader.dbhBufferPtr [i] = doubleBuffer;
  79.     }
  80.     
  81. err = SndPlayDoubleBuffer (chan, &doubleHeader);
  82. if (err != noErr)
  83.     Debugger();
  84.     
  85. do {
  86.     err = SndChannelStatus (chan, sizeof (Stats), &Stats);
  87.     } while (Stats.scChannelBusy);
  88.         
  89. for (i = 0; i <= 1; ++i)
  90.     DisposePtr ((Ptr) doubleHeader.dbhBufferPtr[i]);
  91.  
  92. err = SndDisposeChannel (chan,FALSE);
  93. if (err != noErr)
  94.     Debugger();
  95.         
  96. HUnlock (SoundData);
  97. }
  98. /**********************************/
  99.  
  100. pascal void MyDoubleBackProc (SndChannelPtr chan,SndDoubleBufferPtr doubleBuffer)
  101. {
  102. LocalVarsPtr    myVarsPtr;
  103. long            bytesToCopy;
  104.  
  105. myVarsPtr = (LocalVarsPtr) doubleBuffer->dbUserInfo[0];
  106. bytesToCopy = myVarsPtr->bytesTotal - myVarsPtr->bytesCopied;
  107.  
  108. if (bytesToCopy > kDoubleBufferSize)
  109.     bytesToCopy = kDoubleBufferSize;
  110.     
  111. BlockMove (myVarsPtr->dataPtr, &doubleBuffer->dbSoundData[0], bytesToCopy);
  112.  
  113. doubleBuffer->dbNumFrames = bytesToCopy;
  114. doubleBuffer->dbFlags = (doubleBuffer->dbFlags) | dbBufferReady;
  115.  
  116. myVarsPtr->dataPtr = (Ptr) ((myVarsPtr->dataPtr) + bytesToCopy);
  117. myVarsPtr->bytesCopied = myVarsPtr->bytesCopied + bytesToCopy;
  118.  
  119. if (myVarsPtr->bytesCopied == myVarsPtr->bytesTotal)
  120.     doubleBuffer->dbFlags = (doubleBuffer->dbFlags) | dbLastBuffer;
  121.     
  122. return;
  123. }
  124.  
  125. /**********************************/
  126.